home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DS-CD ROM 2 1993 August
/
DS CD-ROM 2.Ausgabe (August 1993).iso
/
programm
/
ds0257
/
demo.exe
/
LONGINT.DEM
< prev
next >
Wrap
Text File
|
1992-02-16
|
11KB
|
465 lines
; ----------------------------
; LONGINT.DEM - Demo für die Routinen in LONGINT.LIB
;
; (c) Bernd Schemmer 1990 - 1992
; Letzter Update: 15.02.1992
;
; Übersetzen:
; A86 LONGINT.DEM DEMOS.INC TO LONGINT.COM
;
; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
; enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
; erreichbar sein.
;
; ----------------------------
jmp start
logo db CR,LF
db 'LONGINT.DEM - Demo für die Routinen in LONGINT.LIB'
db CR,LF
db '--------------------------------------------------'
db CR,LF
db CR,LF
GETLENGTH Logo
PROMPT1 db
db 'Bitte geben Sie die Rechenart ein (+,-,*,/,\,^ <CR> = '
_opcode0 db '+, X, <ESC> = Ende): '
GETLENGTH Prompt1
PROMPT2 db
db CR,LF
db 'Rechenart: '
_Opcode db 'A --> '
db 'Bitte geben Sie den ersten Operanden ein: '
GETLENGTH Prompt2
PROMPT3 db
db 'Rechenart: '
_Opcode1 db 'A --> '
db 'Bitte geben Sie den zweiten Operanden ein: '
GETLENGTH Prompt3
ResultMSG db
db 'Das Ergebnis ist '
Result db ' '
db CR,LF
GETLENGTH ResultMSG
RestMSG db
db 'Der Rest ist '
Rest db ' '
db CR,LF
GETLENGTH RestMSG
Error1 db 'Falsche Eingabe! (Eingabe zu groß oder Syntax falsch)'
db CR,LF
GETLENGTH Error1
Error2 db 'Fehler beim Rechnen!'
db CR,LF
GETLENGTH Error2
Op1 db 255,256 dup 0
Op2 db 255,256 dup 0
OpCode db '+'
; ----------------------------
Start:
call ShowLogo ; Logo ausgeben und Speicherblock verkleinern
l0: ; Opcode ermitteln
WRITE_STRING Prompt1
l00:
mov ah,08h
int 021h
cmp al,CR
je >l10 ; alten Opcode nochmal benutzen
cmp al,ESC
if e mov al,'X'
cmp al,'X' ; Eingabe auswerten
if e jmp Ende ; Ende
cmp al,'x'
if e jmp Ende
cmp al,'^'
je >l1
cmp al,'+'
je >l1
cmp al,'-'
je >l1
cmp al,'*'
je >l1
cmp al,'\'
je >l1
cmp al,'/'
jne l00 ; Falsche Eingabe
l1:
mov Opcode,al ; Op-Code sichern
mov _Opcode,al ; Op-Code in Meldungen eintragen
mov _Opcode0,al
mov _Opcode1,al
l10:
call ShowCR_LF
l00: ; ersten Operanden lesen
WRITE_STRING Prompt2
mov dx,offset op1
mov ah,0Ah
int 021h
call ShowCR_LF
mov si,offset op1+2 ; Eingabe konvertieren
call GetLongInt
jnc >l1
; Falsche Eingabe
WRITE_STRING error1
jmp l00 ; Eingabe wiederholen
l1:
push cx,bx ; 1. Operanden sichern
l01: ; zweiten Operanden lesen
WRITE_STRING Prompt3
mov dx,offset op2
mov ah,0Ah
int 021h
call ShowCR_LF
; Eingabe konvertieren
mov si,offset op2+2
call GetLongInt
jnc >l1
; Falsche Eingabe
WRITE_STRING error1
jmp l01 ; Eingabe wiederholen
l1:
; 2. Operand steht in CX:BX
pop ax,dx ; 1. Operand nach DX:AX
cmp opcode, '+' ; Opcode auswerten und ausführen
jne >l1
call AddLongInt
clc
jmp >l2
l1:
cmp opcode, '-'
jne >l1
call SubLongInt
clc
jmp >l2
l1:
cmp opcode,'\'
jne >l1
call ModLongInt
jmp >l2
l1:
cmp opcode, '/'
jne >l1
push ax,bx,cx,dx
call DivLongInt ; Ergebnis ermitteln
jc >l10 ; Fehler beim Dividieren!
call ShowResult
pop dx,cx,bx,ax
call ModLongInt ; Rest ermitteln
jc >l2
call ShowRest
jmp l0
l10:
pop dx,cx,bx,ax
jmp >l2
l1:
cmp opcode,'^'
jne >l1
call CalcLongIntPotenz
clc
jmp >l2
l1:
call MulLongInt
clc
l2:
jnc >l1
; Fehler bei der Berechnung
WRITE_STRING error2
jmp >l2
l1: ; Ergebnis ausgeben
Call ShowResult
l2:
jmp l0 ; und nächste Eingabe holen
Ende:
EndProcess 0
; ----------------------------
; GetLongInt
;
; Funktion: Konvertiert die Longint-Variable bei DS:SI nach CX:BX
;
; Ausgabe: CF = 0 -> okay
; CF = 1 -> Fehler
;
GetLongint:
push bp
xor bp,bp ; BP = Vorzeichenmarker
xor bx,bx
xor cx,cx ; CX:BX = Ergebnis -> auf 0 setzen
lodsb ; AL = erstes Zeichen
cmp al,'+'
je >l10 ; + ist Voreinstellung
cmp al,'-'
jne >l1
mov bp,01 ; Marker für negativ setzen
l10:
lodsb ; AL = nächstes Zeichen
l1:
CALL DezDigit?
jc GetLongIntError
mov bl,al ; Ergebnis korrigieren
GetLongInt0:
lodsb ; AL = nächstes Zeichen
cmp al,'.'
je GetLongInt0 ; Punkte als Trenner erlaubt
call DezDigit?
jc GetLongIntOkay
push ax ; alten Wert * 10
mov ax,0Ah
xor dx,dx
call MulLongInt
mov bx,ax
mov cx,dx
pop ax
xor ah,ah ; neue Stelle aufaddieren
add bx,ax
adc cx,0
or cx,cx
js GetLongIntError
jmp GetLongInt0 ; und nächstes Zeichen
GetLongIntOkay:
test ch,080h
jnz GetLongIntError ; Wert zu groß!
or bp,bp
jz GetLongIntOkay1
call ChangeSignCXBX ; Vorzeichen ändern
GetLongIntOkay1:
clc
pop bp
ret
GetLongIntError:
stc
pop bp
ret
; ----------------------------
; ShowResult
;
; Funktion: Ausgabe des Ergebnisses
;
; Eingabe: DX:AX = Ergebnis
;
ShowResult:
push bx
push cx
push dx
push ax
mov di,offset Result
mov b sign,'+'
or dx,dx ; Vorzeichen berücksichtigen
jns >l1
call changesigndxax ; Absolut-Wert ermitteln
mov b sign,'-'
l1:
mov b v0,0
mov cx,03b9Ah
mov bx,0CA00h ; CX:BX = 1.000.000.000
call StoreDezDigit1
mov cx,05F5h ; CX:BX = 100.000.000
mov bx,0E100h
call StoreDezDigit1
mov cx,098h ; CX:BX = 10.000.000
mov bx,09680h
call StoreDezDigit1
mov cx,0Fh ; CX:BX = 1.000.000
mov bx,04240h
call StoreDezDigit1
mov cx,01h
mov bx,086A0h ; CX:BX = 100.000
call StoreDezDigit1
xor cx,cx ; CX:BX = 10.000
mov bx,02710h
call StoreDezDigit1
xor cx,cx ; CX:BX = 1.000
mov bx,03E8h
call StoreDezDigit1
xor cx,cx ; CX:BX = 100
mov bx,064h
call StoreDezDigit1
xor cx,cx ; CX:BX = 10
mov bx,0Ah
call StoreDezDigit1
mov bx,ax ; 1er
cmp v0,0
if z mov b v0,1
call StoreDezDigit2
; Ergebnis ausgeben
WRITE_STRING ResultMSG
pop ax
pop dx
pop cx
pop bx
ret
; ----------------------------
; ShowRest
;
; Funktion: Gibt den Rest einer Division aus
;
; Eingabe: DX:AX = Rest
;
ShowRest:
push ax
push bx
push cx
push dx
mov di,offset Rest
mov b sign,'+'
or dx,dx ; Vorzeichen berücksichtigen
jns >l1
call changesigndxax ; Absolut-Wert ermitteln
mov b sign,'-'
l1:
mov b v0,0
mov cx,03b9Ah
mov bx,0CA00h ; CX:BX = 1.000.000.000
call StoreDezDigit1
mov cx,05F5h ; CX:BX = 100.000.000
mov bx,0E100h
call StoreDezDigit1
mov cx,098h ; CX:BX = 10.000.000
mov bx,09680h
call StoreDezDigit1
mov cx,0Fh ; CX:BX = 1.000.000
mov bx,04240h
call StoreDezDigit1
mov cx,01h
mov bx,086A0h ; CX:BX = 100.000
call StoreDezDigit1
xor cx,cx ; CX:BX = 10.000
mov bx,02710h
call StoreDezDigit1
xor cx,cx ; CX:BX = 1.000
mov bx,03E8h
call StoreDezDigit1
xor cx,cx ; CX:BX = 100
mov bx,064h
call StoreDezDigit1
xor cx,cx ; CX:BX = 10
mov bx,0Ah
call StoreDezDigit1
mov bx,ax ; 1er
cmp v0,0
if z mov b v0,1
call StoreDezDigit2
; Rest ausgeben
WRITE_STRING RestMSG
pop dx
pop cx
pop bx
pop ax
ret
; --------
; Unteroutine von ShowResult
;
v0 db 0
sign db '+'
StoreDezDigit1:
call DivLongInt ; Dividieren
; AL = Ergebnis
StoreDezDigit2:
add al,'0'
cmp v0,2
je >l1
cmp v0,1
je >l00
cmp al,'0'
je >l10
l00:
mov v0,2
mov ah,sign
mov [di],ah
inc di
l1:
stosb
mov dx,cx
mov ax,bx ; Rest nach DX:AX
ret
l10:
mov al,' '
jmp l1
; ----------------------------
; DezDigit?
;
; Funktion: Wandelt das ASCII-Zeichen in AL in dessen binären Wert, falls
; es sich um eine Dezimal-Ziffer handelt. Im Fehlerfall wird das
; Carry-Flag gesetzt
;
; Eingabe: AL = ASCII-Zeichen
;
; Ausgabe: CF = 0 -> okay, AL = Wert
; CF = 1 -> Fehler, AL undefiniert
;
DezDigit?:
sub al,'0'
cmp al,0Ah
cmc
ret
; ----------------------------